﻿using SiMay.Sockets.Tcp.Awaitable;
using System;

namespace SiMay.Sockets.Tcp.Pooling
{
    /// <summary>
    /// 异步操作等待对象池
    /// </summary>
    public class SaeaAwaiterPool : ObjectPool<SaeaAwaiter>
    {
        private Func<SaeaAwaiter> _createSaea;
        private Action<SaeaAwaiter> _cleanSaea;

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="createSaea">创建异步对象方法</param>
        /// <param name="cleanSaea">清除异步对象放方法</param>
        /// <param name="initialCount">初始化对象池里创建多少个异步操作对象</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public SaeaAwaiterPool Initialize(Func<SaeaAwaiter> createSaea, Action<SaeaAwaiter> cleanSaea, int initialCount = 0)
        {
            if (createSaea == null)
                throw new ArgumentNullException("createSaea");
            if (cleanSaea == null)
                throw new ArgumentNullException("cleanSaea");

            _createSaea = createSaea;
            _cleanSaea = cleanSaea;

            if (initialCount < 0)
                throw new ArgumentOutOfRangeException("initialCount", initialCount, "Initial count must not be less than zero.");

            for (int i = 0; i < initialCount; i++)
            {
                Add(Create());
            }

            return this;
        }

        /// <summary>
        /// 调用初始化时设置的创建对象方法
        /// </summary>
        /// <returns></returns>
        protected override SaeaAwaiter Create()
        {
            return _createSaea();
        }

        /// <summary>
        /// 讲异步操作的属性重新设置并放入对象池
        /// </summary>
        /// <param name="saea">异步操作对象</param>
        public void Return(SaeaAwaiter saea)
        {
            _cleanSaea(saea);
            Add(saea);
        }
    }
}
